import json
from google.protobuf.message import Message
from google.protobuf import json_format
from com.util.tcp.functionId_mapper import getResMessageByFunctionId

httpRes = {}


def bytesToHexString(bs):
    """
    将bytes数据转为hex数据
    :param bs: bytes数据
    :return:
    """
    return ''.join(['%02X ' % b for b in bs])


def pb_to_json(pbMessage):
    """
    将pb数据转为json数据
    :param pbMessage:
    :return:
    """
    jsonString = json_format.MessageToJson(pbMessage)
    return jsonString


def json_to_pb(jsonString, pbMessage=Message):
    """
    将json数据转为pb数据
    :param jsonString:
    :param pbMessage:
    :return:
    """
    message = json_format.Parse(json.dumps(jsonString), pbMessage)
    return message


def mockPbMessageBydata(functionId, dictData):
    """
    根据functionId获取映射并根据dictData返回对应的pbMessage
    :param functionId:
    :param dictData:
    :return:
    """
    reqMessage = getResMessageByFunctionId(functionId, 'req')
    pbMessage = reqMessage()
    pbMessage = json_to_pb(dictData, pbMessage)
    return pbMessage


def mockMessageByBodyMessage(functionId, sequeueNo, pbMessage=Message):
    """

    :param functionId: 功能号
    :param pbMessage:
    :param isGY: 是否概要信息
    :return:
    """
    # bodyMessage
    bodyBytes: bytes = pbMessage.SerializeToString()
    # header 加密，h1固定WG，h2长度allLength，h5固定0
    h1 = "WG"
    h2 = int(11) + int(bodyBytes.__len__())
    h3 = int(functionId)
    h4 = int(sequeueNo)
    h5 = 0
    h6 = ""
    # 对（2001概要）单独处理
    if functionId == "2001":
        h5 = 1
        h6 = "5.7.0"

    # 拼接header和body
    hallBytes = mergeHeaderBytes(h1, h2, h3, h4, h5, h6) + bodyBytes
    return hallBytes


def mergeHeaderBytes(h1, h2, h3, h4, h5, h6):
    h1Bytes = h1.encode("utf-8")
    h2Bytes = h2.to_bytes(4, byteorder='big', signed=False)
    h3Bytes = h3.to_bytes(2, byteorder='big', signed=False)
    h4Bytes = h4.to_bytes(2, byteorder='little', signed=False)
    h5Bytes = h5.to_bytes(1, byteorder='little', signed=False)

    h6Bytes = b''
    if h6:
        h6s = h6.split('.')
        h6Bytes1 = int(h6s[0]).to_bytes(1, byteorder='little', signed=False)
        h6Bytes2 = int(h6s[1]).to_bytes(1, byteorder='little', signed=False)
        h6Bytes3 = int(h6s[2]).to_bytes(1, byteorder='little', signed=False)

        h6Bytes = h6Bytes1 + h6Bytes2 + h6Bytes3

    hallBytes = h1Bytes + h2Bytes + h3Bytes + h4Bytes + h5Bytes + h6Bytes
    return hallBytes


def decodeHeader(bs=None):
    # mock数据 h2Hex:Alllength,h3Hex:functionId,h4Hex:sequeueNo
    if bs == None:
        bs = b'WG\x00\x00\x00\x11\x00e\x00\x06\x00'
    h2Hex = bytesToHexString(bs[2:6]).replace(" ", "")
    h3Hex = bytesToHexString(bs[6:8]).replace(" ", "")
    h4Hex = bytesToHexString(bs[8:10]).replace(" ", "")
    alllength = int(h2Hex, 16)
    functionId = str(int(h3Hex, 16))
    sequeueNo = int(h4Hex[2:4] + h4Hex[0:2], 16)

    # 市场概要的header长度为14 需单独处理
    if functionId == "2001":
        lindex = 14
    else:
        lindex = 11
    bodyLength = alllength - lindex
    return {'bodylength': bodyLength, 'lindex': lindex, 'functionId': functionId, "sequeueNo": sequeueNo}


def decodeBody(bsBody=None, functionId='101'):
    # 获取映射
    resMessage: Message = getResMessageByFunctionId(functionId)
    resObj = resMessage()
    resObj.ParseFromString(bsBody)
    jsonRes = json_format.MessageToJson(resObj)
    return jsonRes
